package com.eunion.web.cms.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.eunion.common.util.CommUtils;
import com.eunion.core.PageData;
import com.eunion.web.cms.entity.RecruitStudentsPlan;
import com.eunion.web.cms.entity.ScoreControllerLine;
import com.eunion.web.cms.entity.ScoreRank;
import com.eunion.web.cms.entity.StudentVolunteer;
import com.eunion.web.cms.entity.spec.RecruitStudentsPlanSpec;
import com.eunion.web.cms.entity.spec.ScoreControllerLineSpec;
import com.eunion.web.cms.entity.spec.ScoreRankSpec;
import com.eunion.web.cms.service.RecruitStudentsPlanService;
import com.eunion.web.cms.service.ScoreControllerLineService;
import com.eunion.web.cms.service.ScoreRankService;
import com.eunion.web.cms.service.StudentVolunteerService;
import com.eunion.web.common.base.BaseService;
import com.eunion.web.common.base.BaseTableCommonController;

/**
 * 志愿填报预测
 */
@Controller
@RequestMapping("/api/volunteer-forecast")
@PreAuthorize("hasAuthority('volunteer:forecast')")
public class VolunteerForecastResource extends BaseTableCommonController<RecruitStudentsPlan, Long> {

    private static final int MAX_NUM = 100;
    private static final int MAX_PAGE_NUM = 1000;
    @Autowired
    private StudentVolunteerService studentVolunteerService;
    @Autowired
    private ScoreControllerLineService scoreControllerLineService;
    @Autowired
    private ScoreRankService scoreRankService;
    
    @Override
    protected BaseService<RecruitStudentsPlan, Long> getBaseService() {
        return recruitStudentsPlanService;
    }

    @Autowired
    private RecruitStudentsPlanService recruitStudentsPlanService;

    /**
     * 进入志愿填报预测页面
     * @return
     */
    @RequestMapping("/index")
    public String index() {
        return getUrlBase();
    }

    @Override
    protected String getUrlBase() {
        return "admin/volunteer/volunteer-forecast";
    }

    @RequestMapping(value = "/list", method = {RequestMethod.POST})
    @ResponseBody
    public List<StudentVolunteer> list(@RequestBody RecruitStudentsPlan params) {
        
        ScoreControllerLine controllerLineQuery = new ScoreControllerLine();
        controllerLineQuery.setBatch(params.getBatch());
        controllerLineQuery.setDirection(params.getDirection());
        controllerLineQuery.setProvinceName(params.getProvinceName());
        int requestScore = params.getLowestScore();
        List<String> sortPro = new ArrayList<>();
        sortPro.add("year");
        List<ScoreControllerLine> scoreLines = scoreControllerLineService.findAll(ScoreControllerLineSpec.build(controllerLineQuery,true),new Sort(Sort.Direction.DESC,sortPro));
        List<StudentVolunteer> ret = new ArrayList<>();
        if(CommUtils.isEmpty(scoreLines)){
            return ret;
        }
        if(requestScore > 750 || requestScore < 0) {
            return ret;
        }
        //TODO debug start
        /*for(ScoreControllerLine ss : scoreLines) {
            System.out.println(ss.getYear() + ":" + ss.getLowestScore());
        }*/
        //TODO debug start
        int scoreDiff = requestScore - scoreLines.get(0).getLowestScore();
        if (scoreDiff < 0) {
            return ret;
        }

        ScoreRank scoreRankQuery = new ScoreRank();
        scoreRankQuery.setYear(scoreLines.get(0).getYear());
        scoreRankQuery.setDirection(params.getDirection());
        scoreRankQuery.setScore(requestScore);
        List<String> scoreRankSort = new ArrayList<>();
        scoreRankSort.add("score");
        List<ScoreRank> scooreRanks = scoreRankService.findAll(ScoreRankSpec.build(scoreRankQuery),new Sort(Sort.Direction.ASC,scoreRankSort));
        int rankStart = -1;
        int rankEnd = -1;
        if (!CommUtils.isEmpty(scooreRanks)) {
            String rank = scooreRanks.get(0).getRank();
            if (rank.contains("-")) {
                String[] rankArray = rank.split("-");
                if (rankArray.length == 2) {
                    if (StringUtils.isNumeric(rankArray[0]) && StringUtils.isNumeric(rankArray[1])) {
                        rankStart = Integer.parseInt(rankArray[0]);
                        rankEnd = Integer.parseInt(rankArray[1]);
                    }
                }
            } else {
                if (StringUtils.isNumeric(rank)) {
                    rankStart = rankEnd = Integer.parseInt(rank);
                }
            }
        }
      //TODO debug start
       // System.out.println(rankStart + ";" + rankEnd);
      //TODO debug start
        List<RecruitStudentsPlan> highRateRecruitStudents = new ArrayList<>();
        List<RecruitStudentsPlan> middleRateRecruitStudents = new ArrayList<>();
        List<RecruitStudentsPlan> lowRateRecruitStudents = new ArrayList<>();
        for(ScoreControllerLine socreLine : scoreLines) {
            RecruitStudentsPlan recruitStudentsQuery = new RecruitStudentsPlan();
            recruitStudentsQuery.setProvinceName(params.getProvinceName());
            recruitStudentsQuery.setBatch(params.getBatch());
            recruitStudentsQuery.setDirection(params.getDirection());
            recruitStudentsQuery.setYear(socreLine.getYear());
            recruitStudentsQuery.setLowestScore(socreLine.getLowestScore() + scoreDiff);
            //System.out.println("" + recruitStudentsQuery.getBatch() + ";" + recruitStudentsQuery.getDirection() + ";" + recruitStudentsQuery.getYear() + ";" + recruitStudentsQuery.getLowestScore());
            List<String> lowestScore = new ArrayList<>();
            lowestScore.add("lowestScore");
            PageRequest pageQuery = new PageRequest(0, MAX_PAGE_NUM, new Sort(Sort.Direction.DESC,lowestScore));
            List<RecruitStudentsPlan> recruitStudents = recruitStudentsPlanService.findAll(RecruitStudentsPlanSpec.build(recruitStudentsQuery,RecruitStudentsPlanSpec.HIGH_RATE),pageQuery).getContent();
            if(!CommUtils.isEmpty(recruitStudents)) {
                highRateRecruitStudents.addAll(recruitStudents);
            }
            recruitStudents = recruitStudentsPlanService.findAll(RecruitStudentsPlanSpec.build(recruitStudentsQuery,RecruitStudentsPlanSpec.MIDDLE_RATE),pageQuery).getContent();
            if(!CommUtils.isEmpty(recruitStudents)) {
                middleRateRecruitStudents.addAll(recruitStudents);
            }
            recruitStudents = recruitStudentsPlanService.findAll(RecruitStudentsPlanSpec.build(recruitStudentsQuery,RecruitStudentsPlanSpec.LOW_RATE),pageQuery).getContent();
            if(!CommUtils.isEmpty(recruitStudents)) {
                lowRateRecruitStudents.addAll(recruitStudents);
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("YYYY");
        String year  = sdf.format(new Date());
        toList(year,params,ret,highRateRecruitStudents,"高",rankStart,rankEnd);
        toList(year,params,ret,middleRateRecruitStudents,"中",rankStart,rankEnd);
        toList(year,params,ret,lowRateRecruitStudents,"低",rankStart,rankEnd);
        
        return ret;
    }
    
    private void toList(String year,RecruitStudentsPlan request,List<StudentVolunteer> toView,List<RecruitStudentsPlan> recruitStudents,String rate,int startRank,int endRank) {
        int times = 0;
        for(RecruitStudentsPlan recruitStudent : recruitStudents) {
            if(startRank > 0 && endRank > 0) {
                int rankStart = -1;
                int rankEnd = -1;
                String rank = recruitStudent.getRank();
                if (StringUtils.isNotBlank(rank) && rank.contains("-")) {
                    String[] rankArray = rank.split("-");
                    if (rankArray.length == 2) {
                        if (StringUtils.isNumeric(rankArray[0]) && StringUtils.isNumeric(rankArray[1])) {
                            rankStart = Integer.parseInt(rankArray[0]);
                            rankEnd = Integer.parseInt(rankArray[1]);
                        }
                    }
                } else {
                    if (StringUtils.isNumeric(rank)) {
                        rankStart = rankEnd = Integer.parseInt(rank);
                    }
                }
                if (rankStart > 0 && rankEnd > 0) {
                    if (startRank > rankEnd) {
                        continue;
                    }
                }
            }

            times ++;

            StudentVolunteer studentVolunteer = new StudentVolunteer();
            studentVolunteer.setDirection(request.getDirection());
            studentVolunteer.setCollegeCode(recruitStudent.getCollegeCode());
            studentVolunteer.setCollegeName(recruitStudent.getCollegeName());
            //studentVolunteer.setGender(request.getGender());
            //studentVolunteer.setNickname(request.getUserName());
            //studentVolunteer.setPhone(request.getPhone());
            studentVolunteer.setProvinceName(request.getProvinceName());
            studentVolunteer.setRateName(rate);
            studentVolunteer.setScore(request.getLowestScore());
            studentVolunteer.setBatch(request.getBatch());
            studentVolunteer.setCollegeLowScore(recruitStudent.getLowestScore());
           
            studentVolunteer.setYear(recruitStudent.getYear());
            toView.add(studentVolunteer);
            if(times >= MAX_NUM) {
                return;
            }
        }
        for(RecruitStudentsPlan recruitStudent : recruitStudents) {

            boolean hasAdd = false;
            for (StudentVolunteer dto : toView) {
                if (recruitStudent.getCollegeCode().equals(dto.getCollegeCode())) {
                    hasAdd = true;
                    break;
                }
            }
            if (hasAdd) {
                continue;
            }

            times ++;

            StudentVolunteer studentVolunteer = new StudentVolunteer();
            studentVolunteer.setDirection(request.getDirection());
            studentVolunteer.setCollegeCode(recruitStudent.getCollegeCode());
            studentVolunteer.setCollegeName(recruitStudent.getCollegeName());
            //studentVolunteer.setGender(request.getGender());
            //studentVolunteer.setNickname(request.getUserName());
            //studentVolunteer.setPhone(request.getPhone());
            //studentVolunteer.setProvinceName(request.getProvinceName());
            studentVolunteer.setRateName(rate);
            studentVolunteer.setScore(request.getLowestScore());
            studentVolunteer.setBatch(request.getBatch());
            studentVolunteer.setCollegeLowScore(recruitStudent.getLowestScore());
            studentVolunteer.setYear(recruitStudent.getYear());
            toView.add(studentVolunteer);
            if(times >= MAX_NUM) {
                return;
            }
        }
    }
}
